import os.path
import threading
import time
import json
from fastapi import FastAPI ,WebSocket , Request

from decimal import Decimal
from apilib.component import compManager,TComp
def decimal_default(obj):
    if isinstance(obj, Decimal):
        return float(obj)  # 或者 return str(obj)，根据你的需要选择
    raise TypeError

class TPluginEquts(TComp):
    def __init__(self):
        super().__init__()
        self.compSettings={
            "ovrDBCode":"equ_ovr",
            "dataPath":"/equts2025"
        }
        self.ovrDB = None
        self.matchs ={}
        self.results={}
        self.regResults={}
        self.judgeResults={}
        self.regComps={}
        self.actions={}
        self.handlers={
            "initEventMatchs": self.initEventMatchs ,
            "initMatchDatasC": self.initMatchDatasC ,
            "initMatchDatasJ": self.initMatchDatasJ ,
            "initMatchDatasD": self.initMatchDatasD ,
            "uploadObj": self.uploadObj ,
            "getResultScore": self.getResultScore ,
            "postResultScore": self.postResultScore ,
            "getXcScores": self.getXcScores ,


            "loadInitData": self.loadInitData ,
            "getMatchInfo": self.getMatchInfo,
            "getMatchStartList": self.getMatchStartList
        }
    def getOvrDB(self):
        try:
            if self.ovrDB==None :
                self.ovrDB = self.manager.components[self.compSettings['ovrDBCode']]
        except Exception as er :
            self.manager.log(er)
        return self.ovrDB
    def initEventMatchs(self ):
        res ={}
        try:
            #生成match.json文件 /matchs.json
            #regComp.json文件 /regComps/<eventCode>.json

            queryKey = "getInitDatas"
            ps={}
            queryRes = self.getOvrDB().queryByKey(queryKey , ps)
            regCompFn = os.path.join(self.compSettings['dataPath' ], "regComps.json")
            self.saveObj(queryRes['datasetList'][1] , regCompFn)
            for match in queryRes['datasetList'][0]:
                self.matchs[match['matchCode']] = match
            matchFn = os.path.join(self.compSettings['dataPath' ], "matchs.json")
            self.saveObj(list(self.matchs.values()) , matchFn)

            events = {}
            for regComp in queryRes['datasetList'][1]:
                eventCode = regComp['eventCode']
                if ( eventCode not in events.keys()):
                    events[eventCode] =[]
                events[eventCode].append(regComp)
            for eventCode in events.keys():
                eventRegCompFn = os.path.join(self.compSettings['dataPath' ],"regComps", eventCode+".json")
                self.saveObj(events[eventCode] , eventRegCompFn)
            res = queryRes
        except Exception as er:
            self.manager.log(er)
        return res
    def initMatchDatasC(self):
        res ={
            "status":1
        }
        try:
            #生成matchs_jump.json文件 //matchs_jump.json
            queryRes = self.getOvrDB().queryByKey("getXcMatchs",{ })
            matchs = queryRes['datasetList'][0]
            results = queryRes['datasetList'][1]
            matchsFn = os.path.join(self.compSettings['dataPath'] , f"xc/matchs.json")
            self.saveObj(matchs , matchsFn)

            for match in matchs:
                matchCode = match['matchCode']
                matchResultList = [ r for r in results if r['matchCode'] == matchCode ]
                resultFn = os.path.join(self.compSettings['dataPath'] , f"xc/{matchCode}/results.json")
                self.saveObj(matchResultList , resultFn)
                for score in matchResultList:
                    resultId = score['resultId']
                    scoreFn = os.path.join(self.compSettings['dataPath'], f"xc/{matchCode}/scores/res_{resultId}.json")
                    if os.path.exists(score) :
                        scoreInfo = {
                            "resultId": resultId ,
                            "info":{
                                "irm": "",
                                "start": 0,
                                "end": 0,
                                "pauses": []
                            },
                            "points":[]
                        }
                        self.saveObj(scoreInfo , scoreFn)
        except Exception as er:
            self.manager.log(er)
        return res
    def initMatchDatasJ(self):
        res ={
            "status":1
        }
        try:
            #生成matchs_jump.json文件 //matchs_jump.json
            queryRes = self.getOvrDB().queryByKey("getJumpMatchs",{ })
            matchs = queryRes['datasetList'][0]
            results = queryRes['datasetList'][1]
            matchsFn = os.path.join(self.compSettings['dataPath'] , f"jump/matchs.json")
            self.saveObj(matchs , matchsFn)

            for match in matchs:
                matchCode = match['matchCode']
                matchResultList = [ r for r in results if r['matchCode'] == matchCode ]
                resultFn = os.path.join(self.compSettings['dataPath'] , f"jump/{matchCode}/results.json")
                self.saveObj(matchResultList , resultFn)
        except Exception as er:
            self.manager.log(er)
        return res
    def initMatchDatasD(self, matchCode):
        res ={
            "matchCode": matchCode
        }
        try:
            #生成matchResult.json文件 /<matchCode>/matchResult.json
            queryRes = self.getOvrDB().queryByKey("getMatchStartList",{"matchCode": matchCode})
            results = queryRes['datasetList'][0]
            matchResultFn = os.path.join(self.compSettings['dataPath'] , f"dres/{matchCode}/matchResult.json")
            self.saveObj(results , matchResultFn)
            #生成matchAction.json文件 /<matchCode>/matchAction.json
            actions = queryRes['datasetList'][1]
            matchActionFn = os.path.join(self.compSettings['dataPath'] , f"dres/{matchCode}/matchAction.json")
            self.saveObj(actions , matchActionFn)
            #生成matchInfo.json文件 /<matchCode>/matchInfo.json
            matchInfo = queryRes['datasetList'][2][0]
            matchInfoFn = os.path.join(self.compSettings['dataPath'] , f"dres/{matchCode}/matchInfo.json")
            self.saveObj(matchInfo, matchInfoFn)

            judgeList =[]
            if  matchInfo['judge']!="" :
                judgeList = (matchInfo['judge']).replace("，",",").split(",")
            for result in results:
                result['judgeCodes'] = list(judgeList)
                #生成regResult.json文件  /<matchCode>/results/res_<resultId>.json
                resultId = result['resultId']
                resultFn = os.path.join(self.compSettings['dataPath'] , f"dres/{matchCode}/results/res_{resultId}.json")
                '''
                localResultObj = self.loadObj(resultFn)
                for lk in localResultObj.keys():
                    result[lk] = localResultObj[lk]
                '''
                self.saveObj(result , resultFn)

                #生成regResultScore.json文件  /<matchCode>/results/resScore_<resultId>.json
                resultScoreFn = os.path.join(self.compSettings['dataPath'] , f"dres/{matchCode}/results/resScore_{resultId}.json")
                if( not os.path.exists(resultScoreFn)):
                    self.saveObj({
                        "resultId": resultId
                    } , resultScoreFn)
                for judgeCode in judgeList:
                    #生成judgeResult.json文件 /<matchCode>/results/res_<resultId>_<judgeCode>.json
                    judgeInfo = {
                        "locked":0,
                        "resultId": resultId ,
                        "judgeCode": judgeCode
                    }
                    judgeFn = os.path.join(self.compSettings['dataPath'] , f"dres/{matchCode}/results/res_{resultId}_{judgeCode}.json")
                    localJudgeInfo = self.loadObj(judgeFn)
                    for lk in localJudgeInfo.keys():
                        judgeInfo[lk] = localJudgeInfo[lk]
                    self.saveObj(judgeInfo , judgeFn)
        except Exception as er:
            self.manager.log(er)
        return res
    def uploadObj(self, obj , dataPath):
        res ={
        }
        try:
            fn = matchActionFn = os.path.join(self.compSettings['dataPath'] , dataPath)
            self.saveObj(obj , fn)
            res={
                "status":1
            }
        except Exception as er:
            self.manager.log(er)
        return res
    def loadObj(self ,  fn ):
        res = {}
        try:
            if os.path.exists(fn):
                with open( fn , 'r' , encoding='utf-8') as f :
                    try:
                        res = json.loads(f.read())
                    except Exception as eer:
                        self.manager.log(eer)
        except Exception as er :
            self.manager.log(er)
        return res
    def saveObj(self , obj , fn ):
        try:
            dirName = os.path.dirname(fn)
            if not os.path.exists(dirName):
                os.makedirs(dirName , 0x777)
            with open( fn , 'w' , encoding='utf-8') as f :
                try:
                    f.write(json.dumps(obj , ensure_ascii=False, default=decimal_default))
                except Exception as eer:
                    self.manager.log(eer)

        except Exception as er :
            self.manager.log(er)
    def getTsData(self , dataPath , queryKey , queryPs , updateFlag=False):
        res = {}
        try:
            fn = os.path.join(self.compSettings['dataPath'] , dataPath)
            if ( fn.find(".json")<0):
                fn = fn+".json"
            queryFlag = updateFlag or not os.path.exists(fn)
            if ( queryFlag):
                queryRes = self.ovrDB.queryByKey(queryKey , queryPs)
                self.saveObj(queryRes , fn)
            else:
                res = self.loadObj(fn)
        except Exception as er :
            self.manager.log(er)
        return res
    def loadInitData(self):
        res = {}
        try:
            queryKey = "getInitDatas"
            ps={}
            queryRes = self.getOvrDB().queryByKey(queryKey , ps)
            print('s1', queryRes)
            matchFn = os.path.join(self.compSettings['dataPath' ], "matchs.json")
            self.saveObj(queryRes['datasetList'][0] , matchFn)
            regCompFn = os.path.join(self.compSettings['dataPath' ], "regComps.json")
            self.saveObj(queryRes['datasetList'][1] , regCompFn)
            for match in queryRes['datasetList'][0]:
                self.matchs[match['matchCode']] = match
            for regComp in queryRes['datasetList'][1]:
                self.matchs[regComp['regCompCode']] = regComp
            res = queryRes
        except Exception as er :
            self.manager.log(er)
        return res
    def getMatchInfo(self , matchCode ):
        res = {}
        try:
            if ( matchCode in self.matchs.keys()):
                res = self.matchs[matchCode];
        except Exception as er :
            self.manager.log(er)
        return res
    def loadMatchResult(self , matchCode ):
        res = {}
        try:
            queryKey = "getMatchStartList"
            ps={
                "matchCode":matchCode
            }
            queryRes = self.getOvrDB().queryByKey(queryKey ,ps)
            startListFn = os.path.join(self.compSettings['dataPath' ], "matchData" , matchCode , 'startList.json')
            startList = queryRes['datasetList'][0]
            self.saveObj( startListFn , startList)
            actionFn = os.path.join(self.compSettings['dataPath' ], "matchData" , matchCode , 'action.json')
            actionList = queryRes['datasetList'][1]
            self.saveObj( actionFn , actionList)
            for result in startList:
                judges = result['F_Judge'].split(",")
                for judge in judges:
                    resInfo={
                        "resultId": result['resultId'],


                    }
        except Exception as er :
            self.manager.log(er)
        return res
    def getMatchStartList(self , matchCode , updateFlag=False):
        res = {}
        try:
            queryKey = "getMatchStartList"
            ps={
                "matchCode":matchCode
            }
            datapath = f"startlist/{matchCode}"
            resDatas = self.getTsData(datapath , queryKey , ps , updateFlag)
            res = {
                "result": resDatas['datasetList'][0],
                "action": resDatas['datasetList'][1]
            }
        except Exception as er :
            self.manager.log(er)
        return res
    def fixedFloat(self , value , decSize=3):
        res = value
        try:
            pos = str(value).find(".")
            if ( pos>0):
                strValue = str(value)[0:pos+decSize+1]
                res = float(strValue)
        except Exception as er:
            self.manager.log(er)
        return res
    def getResultScore(self , matchCode ,  resultId):
        respRes = {
            "status":0,
            "result":{}
        }
        res={
            "matchCode": matchCode ,
            "resultId": resultId ,

            "cMax":0,
            "cPenScore":0,
            "cPenPer":0,
            "cPer":0,

            "mMax":0,
            "mPenScore":0,
            "mPenPer":0,
            "mPer":0,

            "per":0 ,

            "judgeScores":{}
        }
        try:
            actionFn = os.path.join(self.compSettings['dataPath'], f"dres/{matchCode}/matchAction.json")
            actions = self.loadObj(actionFn)
            if  os.path.exists(actionFn):
                for action in actions:
                    if action['acClass'] == 'M':
                        res['mMax'] = res['mMax'] + 10 * action['acRate']
                    elif action['acClass'] == 'C':
                        res['cMax'] = res['cMax'] + 10 * action['acRate']
            resultFn = os.path.join(self.compSettings['dataPath'], f"dres/{matchCode}/results/res_{resultId}.json")
            if( os.path.exists(actionFn) and os.path.exists(resultFn)):
                resultInfo = self.loadObj(resultFn)
                judgeNum = len(resultInfo['judgeCodes'])
                if( "judgeCodes" in resultInfo.keys() and  judgeNum>0):
                    mMax = res['mMax']
                    cMax = res['cMax']
                    totalPer = 0
                    total_mPer=0
                    total_cPer=0
                    cJudgeScoreFn = os.path.join(self.compSettings['dataPath'],
                                            f"dres/{matchCode}/results/res_{resultId}_C.json")
                    if os.path.exists(cJudgeScoreFn):
                        cJudgeScoreInfo = self.loadObj(cJudgeScoreFn)
                        for key in ['cPenScore' , 'cPenPer' ,'mPenScore' , 'mPenPer']:
                            if key in  cJudgeScoreInfo.keys():
                                res[key] = cJudgeScoreInfo[key]
                            else:
                                res[key] = 0


                    for judgeCode in resultInfo['judgeCodes']:
                        judgeScoreFn = os.path.join(self.compSettings['dataPath'],
                                                f"dres/{matchCode}/results/res_{resultId}_{judgeCode}.json")
                        res["judgeScores"][judgeCode]={}
                        if (os.path.exists(judgeScoreFn)):
                            judgeScoreInfo = self.loadObj(judgeScoreFn)
                            res["judgeScores"][judgeCode] = judgeScoreInfo
                            cPenScore = res['cPenScore']
                            cPenPer = res['cPenPer']
                            cScore = 0
                            cPer=0
                            mPenScore = res['mPenScore']
                            mPenPer = res['mPenPer']
                            mScore = 0
                            mPer=0
                            per=0
                            for ac in actions:
                                order = ac['acOrder']
                                rate = ac['acRate']
                                classType = ac['acClass']
                                if str(order) in judgeScoreInfo.keys():
                                    value= judgeScoreInfo[str(order)]
                                    if classType=='C':
                                        cScore = cScore + value*rate
                                    elif classType=="M":
                                        mScore = mScore + value*rate
                            if( mMax>0):
                                mPer = (mScore - mPenScore)*100.0/mMax - mPenPer
                                per = mPer
                            if( cMax>0):
                                cPer = (cScore - cPenScore)*100.0/cMax - cPenPer
                            if mMax>0 and cMax>0:
                                per = 0.5* (mPer+cPer)

                            judgeScoreInfo['mScore'] = mScore
                            judgeScoreInfo['mPer'] = self.fixedFloat(mPer,3)
                            judgeScoreInfo['cScore'] = cScore
                            judgeScoreInfo['cPer'] = self.fixedFloat(cPer,3)
                            judgeScoreInfo['per'] = self.fixedFloat(per,3)
                            total_cPer = total_cPer + cPer
                            total_mPer = total_mPer + mPer
                            totalPer = totalPer + per
                    resPer = self.fixedFloat( totalPer *1.0 / judgeNum ,3)
                    resPer_m = self.fixedFloat( total_mPer *1.0 / judgeNum,3)
                    resPer_c = self.fixedFloat( total_cPer *1.0 / judgeNum ,3)
                    res['mPer'] = resPer_m
                    res['cPer'] = resPer_c
                    res['per'] = resPer
                    respRes['status'] = 1
                    respRes['result'] = res
            else:
                respRes['status'] = -1001
        except Exception as er :
            self.manager.log(er)
        respRes['result'] = res
        return respRes
    def postResultScore(self , matchCode ,  resultId):
        res={
            "ResultJson":{},
            "DetailResultJson":[]
        }
        postResult={}
        try:
            scoreResp  = self.getResultScore(matchCode , resultId)
            if ( "status" in scoreResp.keys() and "result" in scoreResp.keys() and scoreResp['status']==1):
                resScore = scoreResp['result']
                mPenScore = resScore['mPenScore']
                res['ResultJson'] = {
                    "ResultId": resultId,
                    "CoursePen": resScore['mPenScore'],
                    "ArtPen": resScore['cPenScore'],
                    "CoursePen":resScore['mPenPer'],
                    "ArtPen":resScore['cPenPer']
                }
                actionFn = os.path.join(self.compSettings['dataPath'], f"dres/{matchCode}/matchAction.json")
                actions = self.loadObj(actionFn)
                for judgeCode in resScore['judgeScores'].keys():
                    judgeScore = resScore['judgeScores'][judgeCode]
                    detailJson = {
                        "ResultId": resultId,
                        "JudgeCode": judgeCode,
                        "P0": mPenScore if judgeScore=='C' else 0,
                        "CourseSum": judgeScore['mScore'],
                        "ArtSum": judgeScore['cScore']
                    }
                    res['DetailResultJson'].append(detailJson)
                    for action in actions:
                        key = "P"+str(action['acOrder'])
                        value = 0
                        if ( str(action['acOrder']) in judgeScore.keys() ):
                            value= judgeScore[str(action['acOrder'])]
                        detailJson[key] = value
                db = self.getOvrDB()

                postParams ={
                    "ResultJson":json.dumps(res["ResultJson"],ensure_ascii=False),
                    "DetailResultJson":json.dumps(res['DetailResultJson'],ensure_ascii=False)
                }
                postResult = db.execProc("Proc_SaveDanceResult" , postParams)
                print(postResult)
        except Exception as er :
            self.manager.log(er)
        return postResult
    def getXcScores(self , matchCode  ):
        respRes = {
            "status":0,
            "scores":{}
        }
        try:
            scorePath = os.path.join(self.compSettings['dataPath'], f"xc/{matchCode}")
            resultFn = os.path.join(scorePath , "results.json")
            results = self.loadObj(resultFn)
            scores ={}
            for result in results:
                resultId = result['resultId']
                scoreFn = os.path.join(scorePath , 'scores' , f"res_{resultId}.json");
                scoreInfo = self.loadObj(scoreFn)
                scores[resultId] = scoreInfo
            respRes['status'] = len(scores)
            respRes['scores'] = scores
        except Exception as er :
            self.manager.log(er)
        return respRes

equtsSettings={
    "ovrDBCode": "equ_ovr",
    "dataPath": "/equts2025"
}
compManager.registComponentType('TPluginEquts' , TPluginEquts , equtsSettings)

